<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class Swoole extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:name';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
        $this->pid_file = '/tmp/websocket.log';
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $action = $this->argument('action');
        switch ($action) {
            case 'stop':   //停止命令
                $this->stop();
                break;
            case 'start':  //启动命令
                $this->start();
                break;
            default:
                $this->error('没有' . $action . '这个命令');
                break;
        }
    }
    /**
     * 这个方法是自己新增的
     * 具体可参考 https://wiki.swoole.com/#/start/start_tcp_server
     */
    public function start()
    {
        $pid = $this->getPid();

        //检测服务是否启动
        if ($pid && Process::kill($pid, 0)) {
            $this->error('服务已启动');
            exit;
        }

        // 这里是监听的服务端口号
        $this->ws = new swoole_websocket_server("localhost", 1215);
        // var_dump($this->ws);
        /*$this->ws->set([
            //60秒检测一次,一个连接如果300秒内未向服务器发送任何数据，此连接将被强制关闭
            'heartbeat_check_interval' => 60,
            'heartbeat_idle_time' => 300,
            //进程id存储路径
            'pid_file' => $this->pid_file,
        ]);*/

        //监听WebSocket连接打开事件
        $this->ws->on('open', function ($ws, $request) {

        });

        //监听WebSocket消息事件
        $this->ws->on('message', function ($ws, $frame) {

            // var_dump($frame);
            echo "Message: {$frame->data}\n";
            $this->ws->push($frame->fd, 'one');
            // $this->info("client is SendMessage4545\n" . $frame);
        });

        //监听WebSocket主动推送消息事件
        $this->ws->on('request', function ($request, $response) {
            $scene = $request->post['scene'];
            var_dump($scene);
            //$this->ws->connections 遍历所有websocket连接用户的fd，给所有用户推送
            foreach ($this->ws->connections as $fd) {
                if ($this->ws->isEstablished($fd)) {
                    $this->ws->push($fd, $scene);
                }
            }
        });

        //监听WebSocket连接关闭事件
        $this->ws->on('close', function ($ws, $fd) {
            $this->info("client is close\n");
        });
        $this->ws->start();
    }

    // 关闭连接
    public function close($swoole, $fd)
    {
        $swoole->close($fd);
    }

    // 服务停止
    public function stop()
    {
        if (!$pid = $this->getPid()) {
            $this->error('没有服务id');
            exit;
        }
        //关闭服务
        if (Process::kill($pid)) {
            $this->info('服务已停止');
            exit;
        }
        $this->info('停止服务失败');
    }

    // 获取进程pid
    private function getPid()
    {
        return file_exists($this->pid_file) ? file_get_contents($this->pid_file) : false;
    }
}
